# pylint: disable=protected-access
import functools
import inspect
import types
from pathlib import Path
from typing import Any

import pandas as pd

import src

_MAX_PARAM_ID_LENGTH = 70


def _get_param_id(obj: Any) -> str:
    if isinstance(obj, pd.DataFrame):
        return f"DataFrame({obj.columns.tolist()})"
    if isinstance(obj, Path):
        return f"//{obj.relative_to(Path(src.__file__).parent.parent)}"
    if isinstance(obj, types.FunctionType):
        return inspect.getsource(obj).strip().strip(",")
    if isinstance(obj, functools.partial):
        return obj.func.__name__
    if isinstance(obj, functools._lru_cache_wrapper):
        return obj.__wrapped__.__name__
    return repr(obj)  # repr here allows to correctly display unicode test ids


def pytest_make_parametrize_id(argname, val):
    """
    This function declares how test ids for `pytest.mark.parametrize` are generated
    """
    param_id = _get_param_id(val)
    if len(param_id) > _MAX_PARAM_ID_LENGTH:
        param_id = f"{param_id[:_MAX_PARAM_ID_LENGTH]} ..."

    return f"{argname}={param_id}"
